home *** CD-ROM | disk | FTP | other *** search
/ Delphi Informant Complete 1995 - 2000 / Delphi Informant Complete 1995 to 2000.iso / Delphi Informant Magazine Complete Works SOURCE CODE 1995.rar / 1995 / SEP / RH9509 / STPWATCH / VTIMERDV.PAS < prev   
Pascal/Delphi Source File  |  1995-08-15  |  2KB  |  76 lines

  1. unit VTimerDv;  { Access the Windows Virtual Timer Device (VTD) }
  2.  
  3. interface
  4.  
  5. function VTD_GetTime: double;
  6.  
  7. implementation
  8.  
  9. const
  10.   { Conversion factor must be a typed constant, since Delphi's built-in
  11.     assembler cannot reference floating point constants by name. }
  12.   SecondsPerTick: double = 0.836E-6;   { Timer rate is 1.196 MHz }
  13.  
  14. var
  15.   VTDSegment: word;
  16.   VTDOffset:  word;
  17.   VTDTicks:   comp;              { 64-bit signed integer }
  18.  
  19. procedure VTD_GetEntryPoint;
  20. begin
  21.   { Call Windows to get address of VTD entry point. }
  22.   asm
  23.     mov ax,$1684                 { Code to ask for an API's entry point }
  24.     mov bx,$05                   { Code for Virtual Timer Device (VTD) }
  25.     xor di,di                    { Clear ES:DI }
  26.     mov es,di
  27.     int $2F                      { Call Windows }
  28.     mov VTDSegment,es            { Save results }
  29.     mov VTDOffset,di
  30.   end;
  31. end;
  32.  
  33. function VTD_GetTime: double;
  34. begin
  35.   { Call VTD to get the elapsed time in seconds since Windows was started. }
  36.   asm
  37.     mov dx,VTDSegment            { Load the entry point }
  38.     mov ax,VTDOffset
  39.  
  40.     push cs                      { Push our call-back address }
  41.     mov bx, offset @RetSpot
  42.     push bx
  43.     push dx                      { Push the entry point }
  44.     push ax
  45.     mov ax,$100                  { Load ID for function VTD_Get_Real_Time }
  46.     retf                         { Call the VTD }
  47.  
  48.   @RetSpot:
  49.     nop                          { Just a place to come home to }
  50.   end;
  51.  
  52.   { The 64-bit tick count is returned in the 32-bit registers EAX and EDX.
  53.     Since Delphi's built-in assembler does not support 32-bit registers,
  54.     use machine code to transfer these registers into the lower and upper
  55.     parts of a 64-bit integer. Then push that 64-bit integer onto the
  56.     coprocessor stack. }
  57.   inline
  58.     (
  59.     $66/                         { Toggle operand size }
  60.     $89/$06/>VTDTicks/           { mov VTDTicks,eax }
  61.     $66/                         { Toggle operand size }
  62.     $89/$16/>VTDTicks+4/         { mov VTDTicks+4,edx }
  63.     $DF/$2E/>VTDTicks            { fild[64] VTDTicks }
  64.     );
  65.  
  66.   { Convert from ticks to seconds. }
  67.   asm
  68.     fmul SecondsPerTick          { Multiply by the conversion factor }
  69.     fstp @result                 { Store in @result and pop the stack }
  70.   end;
  71. end;
  72.  
  73. initialization
  74.   VTD_GetEntryPoint;
  75. end.
  76.